import sim.engine.*;
import sim.display.*;
import sim.portrayal.*;
import sim.portrayal.grid.*;
import sim.portrayal.simple.*;
import sim.util.media.chart.TimeSeriesChartGenerator;

import java.awt.*;

import javax.swing.*;

import org.jfree.data.xy.XYSeries;

public class EpsteinGridUI extends GUIState{
	
	public EpsteinGridUI(){
		super(new EpsteinGrid(System.currentTimeMillis()));
	}
	
	public EpsteinGridUI(SimState state){
		super(state);
	}
	
	public static String getName(){
		return "Epstein Model Grid";
	}
	
	public Display2D display;
	public JFrame displayFrame;
	SparseGridPortrayal2D gridPortrayal = new SparseGridPortrayal2D();
	
	TimeSeriesChartGenerator chart;
	XYSeries active, jailed, quiet;
	
	public void init(Controller c){
		super.init(c);
		
		//Make 2D display
		EpsteinGrid epState = (EpsteinGrid)state;
		display = new Display2D(epState.gridWidth * 10, epState.gridHeight * 10, this);
		displayFrame = display.createFrame();
		c.registerFrame(displayFrame);
		
		//Attach the portrayals
		display.attach(gridPortrayal, "Agents");
		
		//specify the backdrop color
		display.setBackdrop(Color.black);
		
		displayFrame.setVisible(true);	
		
		
		chart = new TimeSeriesChartGenerator();
		chart.setTitle("Epstein Model");
		chart.setYAxisLabel("Agents");
		chart.setXAxisLabel("Time");
		JFrame frame = chart.createFrame(this);
		frame.setVisible(true);
		frame.pack();
		c.registerFrame(frame);
	}
	
	public void setupPortrayals(){
		//tell portrayals what to portray and how to portray them
		gridPortrayal.setField(((EpsteinGrid)state).grid);
		//gridPortrayal.setPortrayalForClass(Civilian.class, new OvalPortrayal2D(Color.green));
		gridPortrayal.setPortrayalForClass(Civilian.class, new CivilianPortrayal());
		gridPortrayal.setPortrayalForClass(Cop.class, new RectanglePortrayal2D(Color.blue));
		gridPortrayal.setPortrayalForNull(new SimplePortrayal2D());
		
		display.reset();	//reschedule the displayer
		display.repaint();	//redraw the display
	}
	
	public void start(){
        super.start();
        setupPortrayals();
        
        chart.removeAllSeries();
		
		active = new XYSeries("Active Count");
		jailed = new XYSeries("Jail Count");
		quiet = new XYSeries("Quiet Count");
		
		chart.addSeries(active, null);
		chart.addSeries(jailed, null);
		chart.addSeries(quiet, null);
		
		scheduleRepeatingImmediatelyAfter(new Steppable(){
			private static final long serialVersionUID = 1L;

			public void step(final SimState state){
				EpsteinGrid epState = (EpsteinGrid)state;
           
				double x = state.schedule.getTime(); 
				int activeY = epState.activeCount;
				int jailedY = epState.jailCount;
				int quietY = epState.quietCount;
           
				// now add the data
				if (x >= Schedule.EPOCH && x < Schedule.AFTER_SIMULATION){
					active.add(x, activeY, true);
					jailed.add(x, jailedY, true);
					quiet.add(x, quietY, true);
				}
			}
       });
    }
	
	public void load(SimState state){
		super.load(state);
		setupPortrayals();
	}
	
	public Object getSimulationInspectedObject() { return state; }
	
	public static void main(String[] args){
		EpsteinGridUI rebUI = new EpsteinGridUI();
		Console c = new Console(rebUI);
		c.setVisible(true);
	}
}
